/*
    实现信息的读取与展示
*/

#include "../include/read.h"
/*
    读取某一行信息，同时可以n-->下一行，p-->上一行
    问题：可以读取到某一行，也可以读取下一行（继续getline），但是如何读取上一行？
    1、每次都从第一行开始吗？先通过输入的n、p确定最终要读取的行，然后从第一行开始读取出来？
    2、直接第一次读取时，全部存到数据结构里，然后就不从文件读取了？
    考虑到读取磁盘更慢，就不频繁读取磁盘了，干脆一次性记录下来算了，也简单些。
*/

// 记录读到的数据
const int carNum = 10;
Student stu[carNum];
CAR car[carNum];
// 将读取到的某一行信息，进行展示
void showInfo(int lineCount)
{
    std::cout << "**********************************************\n";
    std::cout <<"学号-姓名："  << stu[lineCount].studentID << "-" << stu[lineCount].name << std::endl;
    std::cout << "**********************************************\n";
    std::cout  << "智能小车编号：" << car[lineCount].id <<"\n底盘驱动形式: " <<  car[lineCount].basePlate.driveType << "\n底盘最小离地间隙(mm): " << car[lineCount].basePlate.groundClearance << "\n底盘编号:" << car[lineCount].basePlate.id << "\n最大行程(km): " << car[lineCount].basePlate.maxRange << "\n底盘型号:" 
             << car[lineCount].basePlate.model << "\n轮胎1型号: " << car[lineCount].basePlate.tires[0].modelT << "\n轮胎1尺寸(mm): " << car[lineCount].basePlate.tires[0].size << "\n轮胎2型号: " << car[lineCount].basePlate.tires[1].modelT 
             << "\n轮胎2尺寸(mm): " << car[lineCount].basePlate.tires[1].size << "\n轮胎3型号: " << car[lineCount].basePlate.tires[2].modelT << "\n轮胎3尺寸(mm): " << car[lineCount].basePlate.tires[2].size << "\n轮胎4型号: " << car[lineCount].basePlate.tires[3].modelT 
             << "\n轮胎4尺寸(mm): " << car[lineCount].basePlate.tires[3].size << "\n轮距(mm): " << car[lineCount].basePlate.track << "\n最小转弯半径(m): " << car[lineCount].basePlate.turningRadius << "\n轴距(mm): " << car[lineCount].basePlate.wheelbase << "\nAI(TOPS): " << car[lineCount].agx.aiPerformance 
             << "\nCUDA核心: " << car[lineCount].agx.cudaCores << "\n显存(GB): " << car[lineCount].agx.memory << "\nAGX型号: " << car[lineCount].agx.model << "\n存储(GB): " << car[lineCount].agx.storage << "\nTensor CORE: " << car[lineCount].agx.tensorCores
             << "\n摄像头: " << car[lineCount].binocularCamera.camera << "\n深度帧率: " << car[lineCount].binocularCamera.depthFrameRate << "\nFOV-X: " << car[lineCount].binocularCamera.fovX << "\nFOV-Y: " << car[lineCount].binocularCamera.fovY
             << "\n双目摄像头型号: " << car[lineCount].binocularCamera.model << "\nRGB帧率: " << car[lineCount].binocularCamera.rgbFrameRate << "\nRGB帧分辨率-X:" << car[lineCount].binocularCamera.rgbResolutionX << "\nRGB帧分辨率-Y: " << car[lineCount].binocularCamera.rgbResolutionY
             << "\n雷达通道数: " << car[lineCount].ladar.channels << "\n雷达测试范围(m): " << car[lineCount].ladar.maxRange << "\n多线激光雷达型号: " << car[lineCount].ladar.model << "\n雷达功耗(W): " << car[lineCount].ladar.powerConsumed
             << "\n陀螺仪厂家: " << car[lineCount].gyroscope.manufacturer << "\n陀螺仪型号: " << car[lineCount].gyroscope.model
             << "\n显示屏型号: " << car[lineCount].lcd.model << "\n显示屏尺寸: " << car[lineCount].lcd.size
             << "\n电池充电时长(h): " << car[lineCount].battery.chargingTime << "\n对外供电(V): " << car[lineCount].battery.outputVoltage << "\n参数: " << car[lineCount].battery.parameters << std::endl;
    std::cout << "**********************************************\n";
    std::cout << "请输入n显示下一条记录，p显示上一条记录，q退出:\n";
}

void readInfo()
{
    std::string fileName = "./data/info.csv";
    std::ifstream file(fileName);
    if (!file.is_open())
    {
        std::cout << "未找到文件！" << std::endl;
        return;
    }

    // 进行数据读取
    int index = 0;
    std::string line;
    std::getline(file, line);    // 去掉标题行
    while (std::getline(file, line))
    {
        // 把一行的string，变成vector<string>存储
        // 1、正则表达式方式。太耗时了
        // std::regex reg(",");
        // std::sregex_token_iterator iter(line.begin(), line.end(), reg, -1);
        // std::sregex_token_iterator end;
        // std::vector<std::string> tokens(iter, end);

        // 2、stringstream方式。明显更快了。
        std::stringstream ss(line);
        std::string token;
        std::vector<std::string> tokens;
        while (std::getline(ss, token, ','))
        {
            tokens.push_back(token);
        }

        // 将tokens赋值给结构体。
        int i = 0;
        stu[index].studentID = tokens[i++];
        stu[index].name = tokens[i++];
        car[index].id = tokens[i++];
        car[index].basePlate.driveType = tokens[i++];

        car[index].basePlate.groundClearance = std::stoi(tokens[i++]); // 115
        car[index].basePlate.id = tokens[i++];
        car[index].basePlate.maxRange = std::stoi(tokens[i++]); // 10
        car[index].basePlate.model = tokens[i++];
        car[index].basePlate.tires[0].modelT = tokens[i++];
        car[index].basePlate.tires[0].size = std::stoi(tokens[i++]); // 175
        car[index].basePlate.tires[1].modelT = tokens[i++];
        car[index].basePlate.tires[1].size = std::stoi(tokens[i++]); // 175
        car[index].basePlate.tires[2].modelT = tokens[i++];
        car[index].basePlate.tires[2].size = std::stoi(tokens[i++]); // 175
        car[index].basePlate.tires[3].modelT = tokens[i++];
        car[index].basePlate.tires[3].size = std::stoi(tokens[i++]); // 175
        car[index].basePlate.track = std::stoi(tokens[i++]);         // 490
        car[index].basePlate.turningRadius = std::stoi(tokens[i++]); // 0
        car[index].basePlate.wheelbase = std::stoi(tokens[i++]);     // 451
        car[index].agx.aiPerformance = std::stoi(tokens[i++]);       // 32
        car[index].agx.cudaCores = std::stoi(tokens[i++]);           // 512
        car[index].agx.memory = std::stoi(tokens[i++]);              // 32
        car[index].agx.model = tokens[i++];
        car[index].agx.storage = std::stoi(tokens[i++]);     // 32
        car[index].agx.tensorCores = std::stoi(tokens[i++]); // 64
        car[index].binocularCamera.camera = tokens[i++];
        car[index].binocularCamera.depthFrameRate = std::stoi(tokens[i++]); // 90
        car[index].binocularCamera.fovX = std::stoi(tokens[i++]);           // 87
        car[index].binocularCamera.fovY = std::stoi(tokens[i++]);           // 58
        car[index].binocularCamera.model = tokens[i++];
        car[index].binocularCamera.rgbFrameRate = std::stoi(tokens[i++]);   // 30
        car[index].binocularCamera.rgbResolutionX = std::stoi(tokens[i++]); // 1920
        car[index].binocularCamera.rgbResolutionY = std::stoi(tokens[i++]); // 1080
        car[index].ladar.channels = std::stoi(tokens[i++]);                 // 16
        car[index].ladar.maxRange = std::stoi(tokens[i++]);                 // 100
        car[index].ladar.model = tokens[i++];
        car[index].ladar.powerConsumed = std::stoi(tokens[i++]); // 8
        car[index].gyroscope.manufacturer = tokens[i++];
        car[index].gyroscope.model = tokens[i++];
        car[index].lcd.model = tokens[i++];
        car[index].lcd.size = std::stof(tokens[i++]);              // 11.6 注意这里是stof！！！！
        car[index].battery.chargingTime = std::stoi(tokens[i++]);  // 2
        car[index].battery.outputVoltage = std::stoi(tokens[i++]); // 24
        car[index].battery.parameters = tokens[i++];

        index++;
    }

    // 展示信息
    int lineCnt = 0;
    showInfo(lineCnt);
    while (true)
    {
        char choice;
        std::cin >> choice;
        // q退出
        if (choice == 'q')
        {
            break;
        }
        // n下一个
        else if (choice == 'n')
        {
            if (lineCnt != carNum - 1){
                showInfo(++lineCnt);
            }
            else{
                std::cout << "已经是最后一辆! 请重新输入：\n";
            }
        }
        // p上一个
        else if (choice == 'p')
        {
            if (lineCnt != 0){
                showInfo(--lineCnt);            
            }
            else{
                std::cout << "已经是第一辆! 请重新输入：\n";
            }
        }
    }

    // 关闭文件流
    file.close();
}